package zdream.control.foe.mm5bbitter;

import zdream.control.world.buff.AttackModule;
import zdream.control.world.buff.HealthModule;
import zdream.control.world.LevelWorld;
import zdream.control.world.MFoe;
import zdream.control.world.buff.StageModule;
import zdream.control.world.Ticker;

import static zdream.control.world.MFoeConstants.*;

/**
 * <p>5 代会藏到土里面的炮台.
 * <p>
 * <li>不移动, 且位置固定的怪
 * <li>原版伤害4 , 这里改成: 探出头的过程中碰撞伤害 4, 等级 2, 其它时段无碰撞伤害.
 * 在除了藏起来的状态 (stage = 0 或 5), 其它状态炮台都是一个实体, 即不能通过.
 * <li>有敌人在面前时探出头打一枪. 速度比原版快一点
 * <li>HP:2 (512)
 * <li>侦测: 敌人到达面前, 高为2 长为5 的方形区域, 从普通模式转为激活模式.
 * 打一枪之后右缩回去, 转回普通模式.
 * 总的过程: 探出头(0.5 秒) -> 等待(0.083 秒) -> 发子弹
 * -> 等待(0.2 秒) -> 缩回去(0.5 秒) -> CD (0.5秒)
 * <li>子弹: 7.5 块/秒
 * </li></p>
 *
 * @author Zdream
 * @date 2020-06-13 (created)
 * @date 2022-06-10
 */
public class MM5BBitter extends MFoe {
	public static final String NAME = "MM5BBitter";

	public MM5BBitter(LevelWorld world) {
		super(world);
		this.type = TYPE_FOE;
		this.side = SIDE_ENEMY;
	}

	@Override
	public String foeName() {
		return NAME;
	}

	@Override
	public void init() {
		createNormalPattern()
				// 锚点在下底的中点偏左
				.withRectangle(-0.375f, 0, 0.75f, 0.25f)
				.apply();
		createPattern("appear1").withRectangle(-0.375f, 0, 0.75f, 0.625f);
		createPattern("appear2").withRectangle(-0.375f, 0, 0.75f, 7/6f);
		createPattern("appear3").withRectangle(-0.375f, 0, 0.75f, 5/3f);
		// 没有 4
		createPattern("appear5").withRectangle(-0.375f, 0, 0.75f, 1.458f);

		healthModule = buildHealthModule()
				.hpMax(2)
				.create();
		attackModule = buildAttackModule()
				.damageLevel(DAMAGE_LEVEL_BODY)
				.targetTypesIsEntity()
				.create();
		stageModule = buildStageModule()
				.defineInitStage(STAGE_WAIT, this::handleWaitStage)
				.defineStage(STAGE_APPEAR, this::handleAppearStage)
				.defineStage(STAGE_SHOT, this::handleShotStage)
				.defineStage(STAGE_SHOW, this::handleShowStage)
				.defineStage(STAGE_HIDE, this::handleHideStage)
				.defineStage(STAGE_SLEEP, this::handleSleepStage)
				.create();
	}

	@Override
	public boolean is(String category) {
		if (super.is(category)) {
			return true;
		}
		if ("speciesA".equals(category)) {
			return species == 0;
		}
		if ("speciesB".equals(category)) {
			return species == 1;
		}
		return false;
	}

	/**
	 * 0 - 红色种
	 * 1 - 绿色种
	 */
	byte species;

	public HealthModule healthModule;
	public AttackModule attackModule;
	public StageModule stageModule;

	/* **********
	 *   阶段   *
	 ********** */
	public static final String STAGE_WAIT = "wait";
	public static final String STAGE_APPEAR = "appear";
	public static final String STAGE_SHOT = "shot";
	public static final String STAGE_SHOW = "show";
	public static final String STAGE_HIDE = "hide";
	public static final String STAGE_SLEEP = "sleep";

	private void handleWaitStage(StageModule s, Ticker ticker) {
		float px = (orientation) ? pos.x : pos.x + pos.width - 5;
		MFoe enemy = s.findNearestEnemy(px, getCenterY() - 1, 5, 2);
		if (enemy != null) {
			// 激活
			s.changeStageTo(STAGE_APPEAR);
			attackModule.setDamage(4, DAMAGE_LEVEL_BODY);
			applyPattern("appear1");
		}
	}

	private void handleAppearStage(StageModule s, Ticker ticker) {
		setTerrainWithSides(BOX_TERRAIN_SOFT_SOLID, SIDE_PLAYER, SIDE_ENEMY, SIDE_NEUTRAL, SIDE_OTHER);

		long stageDuration = s.stageDuration;
		if (stageDuration >= 500) {
			applyPattern("appear5");
			attackModule.clearDamage();
			s.changeStageTo(STAGE_SHOT);
		} else if (stageDuration >= 200) {
			applyPattern("appear3");
		} else if (stageDuration >= 100) {
			applyPattern("appear2");
		}
	}
	
	private void handleShotStage(StageModule s, Ticker ticker) {
		if (s.stageDuration >= 133) {
			shot();
			s.changeStageTo(STAGE_SHOW);
		}
	}

	private void handleShowStage(StageModule s, Ticker ticker) {
		if (s.stageDuration >= 200) {
			s.changeStageTo(STAGE_HIDE);
		}
	}

	private void handleHideStage(StageModule s, Ticker ticker) {
		long stageDuration = s.stageDuration;
		if (stageDuration >= 500) {
			applyPattern(PATTERN_NORMAL);
			s.changeStageTo(STAGE_SLEEP);
			clearTerrainWithSide(SIDE_PLAYER);
			clearTerrainWithSide(SIDE_ENEMY);
			clearTerrainWithSide(SIDE_OTHER);
		} else if (stageDuration >= 400) {
			applyPattern("appear1");
		} else if (stageDuration >= 300) {
			applyPattern("appear2");
		}
	}

	private void handleSleepStage(StageModule s, Ticker ticker) {
		if (s.stageDuration >= 500) {
			s.changeStageTo(STAGE_WAIT);
		}
	}

	private void shot() {
		MM5BBitterBullet bullet = new MM5BBitterBullet(this);

		float bulletX, bulletY = anchorY + 1.041667f, vx;

		if (orientation) {
			bulletX = anchorX + 0.833333f;
			vx = 7.5f;
		} else {
			bulletX = anchorX - 0.833333f;
			vx = -7.5f;
		}

		bullet.setVelocity(vx);
		world.createFoe(bullet, bulletX, bulletY, orientation);
	}
}
